<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/6/8
 * Time: 16:38
 */

class WxOpen{
    protected $CONFIG_NAME = 'WXOPEN';
    public  function __construct($config_name = false){
        if($config_name){
            $this->CONFIG_NAME = $config_name;
        }
    }

    //获取component_access_token
    public function get_component_access_token() {
        $weixin_url = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
        $weixin = config($this->CONFIG_NAME);
        if($weixin){
            $file_path = "./access_token/component_access_token_".$weixin["weixin_appid"].".json";
            $data = is_file($file_path)?json_decode(file_get_contents($file_path)):(object)[];
            if (!isset($data->expire_time)||$data->expire_time < time()) {
                $component_verify_ticket = $this->get_component_verify_ticket();
                if(!$component_verify_ticket) return false;
                $res = $this->curl_post($weixin_url,json_encode([
                    'component_appid'=>$weixin["weixin_appid"],
                    'component_appsecret'=>$weixin["weixin_secret"],
                    'component_verify_ticket'=>$component_verify_ticket,
                ]));
                $res = json_decode($res);
                if(isset($res->errcode)) return false;
                $access_token = $res->component_access_token;
                $data->expire_time = time() + $res->expires_in - 200;
                $data->access_token = $access_token;
                file_put_contents("./access_token/component_access_token_".$weixin["weixin_appid"].".json",json_encode($data));
            }
            else{
                $access_token = $data->access_token;
            }
            return $access_token;
        }
        else{
            return false;
        }
    }
    //获取预授权码pre_auth_code
    public function get_pre_auth_code() {
        $weixin_url = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=".$this->get_component_access_token();
        $weixin = config($this->CONFIG_NAME);
        if($weixin){
            $key = 'pre_auth_code_'.$weixin["weixin_appid"];
            $data = ZC($key);
            if (!$data) {
                $res = $this->curl_post($weixin_url,json_encode([
                    'component_appid'=>$weixin["weixin_appid"],
                ]));
                $res = json_decode($res);
                if(isset($res->errcode)) return false;
                $pre_auth_code = $res->pre_auth_code;
                ZC($key,$pre_auth_code,$res->expires_in - 100);
            }
            else{
                $pre_auth_code = $data;
            }
            return $pre_auth_code;
        }
        else{
            return false;
        }
    }
    //记录component_verify_ticket
    public function set_component_verify_ticket($encryptMsg,$input){
        $weixin = config($this->CONFIG_NAME);
        \think\Loader::import('wxBizMsgCrypt', EXTEND_PATH.'WxOpen/');
        $xml_tree = new DOMDocument();
        $encryptMsg = $encryptMsg?$encryptMsg:123;
        $xml_tree->loadXML($encryptMsg);
        $array_e = $xml_tree->getElementsByTagName('Encrypt');
        $encrypt = $array_e->item(0)->nodeValue;

        $_pc = new Prpcrypt($weixin['key']);
        $result = $_pc->decrypt($encrypt, $weixin['weixin_appid']);

        //var_dump($result);
        $xml_tree = new DOMDocument();
        $xml_tree->loadXML($result[1]);
        $array_a = $xml_tree->getElementsByTagName('ComponentVerifyTicket');
        $component_verify_ticket = $array_a->item(0)->nodeValue;

        file_put_contents('./access_token/component_verify_ticket_'.$weixin["weixin_appid"].'.json',$component_verify_ticket);
        return $component_verify_ticket;
    }

    //获取component_verify_ticket
    public function get_component_verify_ticket(){
        $weixin = config($this->CONFIG_NAME);
        $file_path = "./access_token/component_verify_ticket_".$weixin["weixin_appid"].".json";
        $component_verify_ticket = is_file($file_path)?file_get_contents($file_path):false;
        return $component_verify_ticket;
    }

    //授权后设置信息
    public function set_auth_info($auth_code){
        $weixin_url = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=".$this->get_component_access_token();
        $weixin = config($this->CONFIG_NAME);

        $res = $this->curl_post($weixin_url,json_encode([
            "component_appid"=>$weixin["weixin_appid"],
            "authorization_code"=>$auth_code
        ]));
        $res = json_decode($res,true);
        if(isset($res['errcode'])) return false;
        $res['authorization_info']['func_info'] = json_encode($res['authorization_info']['func_info']);
        $res['authorization_info']['expires_time'] = time()+$res['authorization_info']['expires_in']-500;
        unset($res['authorization_info']['expires_in']);
        $wxapp_id = \think\Db::name('wxapp')->where(['authorizer_appid'=>$res['authorization_info']['authorizer_appid']])->value('wxapp_id');
        if($wxapp_id){
            \think\Db::name('wxapp')->where('wxapp_id',$wxapp_id)->update($res['authorization_info']);
        }
        else{
            $wxapp_id = \think\Db::name('wxapp')->insertGetId($res['authorization_info']);
        }
        $res = $res['authorization_info'];
        $res['wxapp_id'] = $wxapp_id;
        return $res;
    }

    //获取authorizer_access_token
    public function get_authorizer_access_token($wxapp_id){
        $key = 'get_authorizer_access_token_'.$wxapp_id;
        $value = ZC($key);
        //$value = false;
        if(!$value){
            $value = \think\Db::name('wxapp')->where(['wxapp_id'=>$wxapp_id])->find();
            if(!$value) return false;

            //var_dump($value);
            if($value['expires_time'] <= time()){
                $refresh_res = $this->refresh_authorizer_access_token($value['authorizer_appid'],$value['authorizer_refresh_token']);
                $value['expires_time'] = $refresh_res['expires_time'];
                $value['authorizer_access_token'] = $refresh_res['authorizer_access_token'];
                $value['authorizer_refresh_token'] = $refresh_res['authorizer_refresh_token'];
            }

            ZC($key,$value,$value['expires_time']-time());
        }
        return $value['authorizer_access_token'];
    }

    //刷新authorizer_access_token
    public function refresh_authorizer_access_token($authorizer_appid,$authorizer_refresh_token){
        $weixin_url = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=".$this->get_component_access_token();
        $weixin = config($this->CONFIG_NAME);
        $res = $this->curl_post($weixin_url,json_encode([
            "component_appid"=>$weixin["weixin_appid"],
            "authorizer_appid"=>$authorizer_appid,
            "authorizer_refresh_token"=>$authorizer_refresh_token
        ]));
        $res = json_decode($res,true);
        if(isset($res['errcode'])) return false;
        $wxapp_info = [];
        $wxapp_info['expires_time'] = time()+$res['expires_in']-500;
        $wxapp_info['authorizer_access_token'] = $res['authorizer_access_token'];
        $wxapp_info['authorizer_refresh_token'] = $res['authorizer_refresh_token'];
        \think\Db::name('wxapp')->where('authorizer_appid',$authorizer_appid)->update($wxapp_info);
        $res = $wxapp_info;
        return $res;
    }

    public function curl_post($url, $post=array()) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);//解决 Problem (2) in the Chunked-Encoded data！！！
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1); //是否抓取跳转后的页面
        $return = curl_exec ($ch);
        curl_close($ch);
        return $return;
    }
}